package com.yifeng.repo.base.utils.file;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.nio.charset.Charset;
import java.util.zip.CRC32;
import java.util.zip.CheckedInputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;

/**
 * ZIP解压工具类
 */
public class ZipDecompress {

    private static final int BUFFER = 1024;

    /**
     * 文件 解压缩
     *
     * @param srcPath 源文件路径
     * @return boolean
     */
    public static boolean decompress(String srcPath) {
        boolean suc = true;
        try {
            File srcFile = new File(srcPath);
            decompress(srcFile);
        } catch (Exception e) {
            suc = false;
            e.printStackTrace();
        }
        return suc;
    }

    /**
     * 解压缩
     *
     * @param srcFile srcFile
     * @throws Exception
     */
    public static void decompress(File srcFile) throws Exception {
        String basePath = srcFile.getParent();
        decompress(srcFile, basePath);
    }

    /**
     * 解压缩
     *
     * @param srcFile  srcFile
     * @param destFile destPath
     * @throws Exception
     */
    public static void decompress(File srcFile, File destFile) throws Exception {

        CheckedInputStream cis = new CheckedInputStream(new FileInputStream(
                srcFile), new CRC32());

        ZipInputStream zis = new ZipInputStream(cis, Charset.forName("GBK"));

        decompress(destFile, zis);

        zis.close();

    }

    /**
     * 解压缩
     *
     * @param srcFile  srcFile
     * @param destPath destPath
     * @throws Exception
     */
    public static void decompress(File srcFile, String destPath) throws Exception {
        decompress(srcFile, new File(destPath));

    }

    /**
     * 文件 解压缩
     *
     * @param srcPath  源文件路径
     * @param destPath 目标文件路径
     */
    public static boolean decompress(String srcPath, String destPath) {
        boolean suc = true;
        try {
            File srcFile = new File(srcPath);
            decompress(srcFile, destPath);
        } catch (Exception e) {
            suc = false;
            e.printStackTrace();
        }
        return suc;
    }

    /**
     * 文件 解压缩
     *
     * @param destFile 目标文件
     * @param zis      ZipInputStream
     * @throws Exception
     */
    private static void decompress(File destFile, ZipInputStream zis) throws Exception {

        ZipEntry entry;
        while ((entry = zis.getNextEntry()) != null) {

            // 文件
            String dir = destFile.getPath() + File.separator + entry.getName();

            File dirFile = new File(dir);

            // 文件检查
            fileProber(dirFile);

            if (entry.isDirectory()) {
                dirFile.mkdirs();
            } else {
                decompressFile(dirFile, zis);
            }

            zis.closeEntry();
        }
    }

    /**
     * 文件探针
     * 当父目录不存在时，创建目录！
     *
     * @param dirFile dirFile
     */
    private static void fileProber(File dirFile) {

        File parentFile = dirFile.getParentFile();
        if (!parentFile.exists()) {

            // 递归寻找上级目录
            fileProber(parentFile);

            parentFile.mkdir();
        }

    }

    /**
     * 文件解压缩
     *
     * @param destFile 目标文件
     * @param zis      ZipInputStream
     * @throws Exception
     */
    private static void decompressFile(File destFile, ZipInputStream zis) throws Exception {

        BufferedOutputStream bos = new BufferedOutputStream(
                new FileOutputStream(destFile));

        int count;
        byte[] data = new byte[BUFFER];
        while ((count = zis.read(data, 0, BUFFER)) != -1) {
            bos.write(data, 0, count);
        }

        bos.close();
    }
}